home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / mui / MCC_SettingsWi.lha / MCC_SettingsWindow / Sources / SettingsWindow_c.c next >
C/C++ Source or Header  |  1998-07-20  |  40KB  |  1,800 lines

  1. /* SettingsWindow_c.c
  2. ** Copyright 1997-98 by Ingo Weinhold.
  3. **
  4. ** This file contains the sources for class and some library stuff.
  5. ** Since I didn't get any of these completely C-written MCC templates
  6. ** working with my MAXON compiler/linker, I had to use a little
  7. ** assembler stub (SettingsWindow_mcc.s).
  8. ** I put the functions managing the complex (nested) structures and
  9. ** the lists in another file (StructSupport.h) that is included
  10. ** directly (uuhhhh) due to some strange problems with the linker.
  11. ** Most of the code was hacked together in August/September 1997 and
  12. ** seeing it now (Juli 1998) gives me the creeps.
  13. **
  14. ** You are allowed to recycle any line of code you want.
  15. ** If you want to write a custom class you need to use your own tag
  16. ** base (derived from your registration number) of course.
  17. */
  18.  
  19. /* MUI */
  20.  
  21. #include <libraries/mui.h>
  22. #include <MUI/NList_mcc.h>
  23.  
  24.  
  25. /* System */
  26.  
  27. #include <exec/types.h>
  28. #include <exec/memory.h>
  29. #include <libraries/gadtools.h>
  30.  
  31.  
  32. /* Prototypes */
  33.  
  34. #include <clib/alib_protos.h>
  35. #include <clib/exec_protos.h>
  36. #include <clib/dos_protos.h>
  37. #include <clib/graphics_protos.h>
  38. #include <clib/utility_protos.h>
  39. #include <clib/muimaster_protos.h>
  40. #include <clib/asl_protos.h>
  41. #include <clib/locale_protos.h>
  42.  
  43.  
  44. /* ANSI C */
  45.  
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <stdio.h>
  49.  
  50.  
  51. /* Compiler specific stuff */
  52.  
  53. #define REG(x) register __ ## x
  54. #define ASM
  55. #define SAVEDS
  56.  
  57.  
  58. /* Useful stuff */
  59.  
  60. #define FChild (MUIA_Family_Child)
  61. #define IsMinListEmpty(ml)      IsListEmpty((struct List *)(ml))
  62.  
  63.  
  64. /* Pragmas */
  65.  
  66. #include <pragma/exec_lib.h>
  67. #include <pragma/dos_lib.h>
  68. #include <pragma/graphics_lib.h>
  69. #include <pragma/utility_lib.h>
  70.  
  71.  
  72. /* Locale stuff */
  73.  
  74. #define CATCOMP_NUMBERS
  75. #define CATCOMP_ARRAY
  76. #include "SettingsWindow_mcc.lh"
  77.  
  78.  
  79. #include "SettingsWindow_mcc.h"
  80.  
  81. struct Library *MUIClassBase;
  82. struct Library *MUIMasterBase;
  83. struct Library *SysBase;
  84. struct Library *UtilityBase;
  85. extern struct Library *DOSBase;
  86. struct Library *IntuitionBase;
  87. struct Library *GfxBase;
  88. struct Library *AslBase;
  89. struct Library *LocaleBase;
  90.  
  91. struct Catalog *Catalog;
  92.  
  93. static struct MUI_CustomClass *ThisClass;
  94.  
  95. #define CLASS            MUIC_SettingsWindow
  96. #define SUPERCLASS    MUIC_Window
  97.  
  98.  
  99. /* Debugging Stuff */
  100.  
  101. #define DEBUG    0
  102.  
  103. #define DBFILENAME    "CON:10/10/500/400"
  104.  
  105. #if DEBUG>0
  106.     FILE *DBFILE;
  107.  
  108.     #define DBINIT                                    \
  109.         DBFILE=freopen(DBFILENAME,"w",stdout)
  110.  
  111.  
  112.     #define DBEXIT                    \
  113.         if (DBFILE)                    \
  114.             {                            \
  115.             fclose(DBFILE);        \
  116.             }
  117.  
  118.     #define D(bug)    {bug}
  119.     #define BUG        printf
  120. #else
  121.     #define DBINIT
  122.     #define DBEXIT
  123.     #define D(bug)
  124. #endif
  125.  
  126. #if DEBUG>1
  127.     #define D2(bug)    {bug}
  128. #else
  129.     #define D2(bug)
  130. #endif
  131.  
  132.  
  133.  
  134. /* Locale support functions */
  135.  
  136. void InitLocale()
  137. {
  138.     if (LocaleBase = OpenLibrary("locale.library",38))
  139.         {
  140.         Catalog = OpenCatalog(NULL,"SettingsWindow_mcc.catalog",
  141.             OC_Version, 0,
  142.             TAG_DONE);
  143.         }
  144. }
  145.  
  146.  
  147. void ExitLocale()
  148. {
  149.     if (LocaleBase)
  150.         {
  151.         if (Catalog)
  152.             {
  153.             CloseCatalog(Catalog);
  154.             }
  155.  
  156.         CloseLibrary(LocaleBase);
  157.         }
  158. }
  159.  
  160.  
  161. STRPTR GetStr(int num)
  162. {
  163.     struct CatCompArrayType *cca = (struct CatCompArrayType *)CatCompArray;
  164.  
  165.     while (cca->cca_ID != num) cca++;
  166.  
  167.     if (LocaleBase)
  168.         {
  169.         return(GetCatalogStr(Catalog,num,cca->cca_Str));
  170.         }
  171.  
  172.     return((char *)cca->cca_Str);
  173. }
  174.  
  175.  
  176. Object *MakeButton(int num)
  177. {
  178.     return(SimpleButton(GetStr(num)));
  179. }
  180.  
  181. /* Memory pool supporting functions */
  182.  
  183. void *AllocVecPooled(REG(a0) void *pool, REG(d0) ULONG size)
  184. {
  185.     ULONG *mem;
  186.  
  187.     size+=4;
  188.  
  189.     if (mem=AllocPooled(pool,size))
  190.         {
  191.         mem[0]=size;
  192.         mem=&mem[1];
  193.         }
  194.  
  195.     return(mem);
  196. }
  197.  
  198.  
  199. void FreeVecPooled(void *pool, void *mem)
  200. {
  201.     mem=&((ULONG *)mem)[-1];
  202.  
  203.     FreePooled(pool,mem,*(ULONG *)mem);
  204. }
  205.  
  206.  
  207. /* a strdup that works on a memory pool */
  208.  
  209. char *strdupp(void *pool, const char *str)
  210. {
  211.     char *res = 0;
  212.     if (str)
  213.     {
  214.         if (res = AllocVecPooled(pool, strlen(str) + 1))
  215.             strcpy(res, str);
  216.     }
  217.     return res;
  218. }
  219.  
  220.  
  221.  
  222. /**************************/
  223. /*  SettingsWindow-CLASS  */
  224. /**************************/
  225.  
  226.  
  227. struct SettingsWindow_Data
  228. {
  229.     ULONG itemnum;
  230.     struct MUIS_SettingsWindow_Item *items;
  231.     ULONG *defitems;
  232.     ULONG usedefaults;
  233.     ULONG nonotify;
  234.     struct MinList    notifylist;
  235.     ULONG portdirectly;
  236.     ULONG testmode;
  237.     void    *pool;
  238.     ULONG changed;
  239. };
  240.  
  241.  
  242. /* Private Structures */
  243.  
  244. struct MUIS_SettingsWindow_Item
  245. {
  246.     Object    *swi_Obj;
  247.     ULONG        swi_Attr;
  248.     ULONG        swi_Type;
  249.     ULONG        swi_Size;
  250.     ULONG        swi_ID;
  251.     ULONG        swi_Contents;
  252. };
  253.  
  254. struct MUIS_SettingsWindow_ComplexContents
  255. {
  256.     ULONG    swc_Reloc;
  257.     ULONG    swc_Size;
  258.     UBYTE    swc_Entry[0];
  259. };
  260.  
  261. struct MUIS_SettingsWindow_ListContents
  262. {
  263.     ULONG    swl_Reloc;
  264.     ULONG    swl_Size;
  265.     ULONG    swl_Count;
  266.     ULONG    swl_Entries[0];
  267. };
  268.  
  269. struct NotifyEntry
  270. {
  271.     struct MinNode ne_Node;
  272.     ULONG                ne_TrigID;
  273.     ULONG                ne_TrigValue;
  274.     Object             *ne_DestObj;
  275.     ULONG                ne_FollowParams;
  276.     ULONG                ne_Params[0];
  277. };
  278.  
  279. #define NOTIFYSIZE(params)    (sizeof(struct NotifyEntry)-sizeof(struct MinNode)+4*(params))
  280.  
  281.  
  282. #define CASE_LIST                    \
  283.     case SWIT_LISTSTANDARD:        \
  284.     case SWIT_LISTSTRING:        \
  285.     case SWIT_LISTSTRUCT:        \
  286.     case SWIT_LISTCOMPLEX:        \
  287.     case SWIT_LISTCUSTOM
  288.  
  289.  
  290. /* Structure Support */
  291.  
  292. #include "StructSupport.h"
  293.  
  294.  
  295. /* Initial TagList */
  296.  
  297. static TagItem InitTagList[]={
  298.     {MUIA_Window_Menustrip, NULL},
  299.     {TAG_MORE,NULL}};
  300.  
  301.  
  302. /*    Menu Return-Values */
  303.  
  304. #define menu_quit                0x01
  305. #define menu_load                0x02
  306. #define menu_lastsaved        0x03
  307. #define menu_restore            0x04
  308. #define menu_saveas            0x05
  309. #define menu_defaults        0x06
  310.  
  311.  
  312. /* Prototypes */
  313.  
  314. static ULONG SettingsWindow_GetItemNum(Object *obj,
  315.     struct SettingsWindow_Data *data, ULONG num);
  316.  
  317.  
  318.  
  319. static ULONG SettingsWindow_New(struct IClass *cl,Object *obj,struct opSet *msg)
  320. {
  321.     struct SettingsWindow_Data *data;
  322.     BOOL  erfolg=FALSE;
  323.     ULONG testbutton=GetTagData(MUIA_SettingsWindow_TestButton,FALSE,msg->ops_AttrList);
  324.     ULONG usedefaults=GetTagData(MUIA_SettingsWindow_UseDefaults,TRUE,msg->ops_AttrList);
  325.  
  326.     Object *buttongroup;
  327.     Object *bu_save,*bu_use,*bu_test,*bu_cancel;
  328.     TagItem *roottag;
  329.  
  330.     D(BUG("New! True Class: %p\n",obj));
  331.  
  332.     /* insert InitTagList */
  333.  
  334.     InitTagList[sizeof(InitTagList)/sizeof(struct TagItem)-1].ti_Data=(ULONG)msg->ops_AttrList;
  335.     msg->ops_AttrList=InitTagList;
  336.  
  337.     /*    Menu */
  338.  
  339.     InitTagList[0].ti_Data=(ULONG)MenustripObject,
  340.         FChild, MenuObject,
  341.             MUIA_Menu_Title, GetStr(MSG_MENU_PROJECT),
  342.             FChild, MenuitemObject,
  343.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_PROJECT_OPEN),
  344.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_PROJECT_OPEN_SHORT),
  345.                 MUIA_UserData, menu_load,
  346.                 End,
  347.             FChild, MenuitemObject,
  348.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_PROJECT_SAVEAS),
  349.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_PROJECT_SAVEAS_SHORT),
  350.                 MUIA_UserData, menu_saveas,
  351.                 End,
  352.             FChild, MenuitemObject,
  353.                 MUIA_Menuitem_Title, NM_BARLABEL,
  354.                 End,
  355.             FChild, MenuitemObject,
  356.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_PROJECT_QUIT),
  357.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_PROJECT_QUIT_SHORT),
  358.                 MUIA_UserData, menu_quit,
  359.                 End,
  360.             End,
  361.  
  362.         FChild, MenuObject,
  363.             MUIA_Menu_Title, GetStr(MSG_MENU_EDIT),
  364.             FChild, MenuitemObject,
  365.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_EDIT_DEFAULTS),
  366.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_EDIT_DEFAULTS_SHORT),
  367.                 MUIA_UserData, menu_defaults,
  368.                 End,
  369.             FChild, MenuitemObject,
  370.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_EDIT_LASTSAVED),
  371.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_EDIT_LASTSAVED_SHORT),
  372.                 MUIA_UserData, menu_lastsaved,
  373.                 End,
  374.             FChild, MenuitemObject,
  375.                 MUIA_Menuitem_Title,GetStr(MSG_MENU_EDIT_RESTORE),
  376.                 MUIA_Menuitem_Shortcut,GetStr(MSG_MENU_EDIT_RESTORE_SHORT),
  377.                 MUIA_UserData, menu_restore,
  378.                 End,
  379.             End,
  380.         End;
  381.  
  382.  
  383.     if (roottag=FindTagItem(MUIA_Window_RootObject,msg->ops_AttrList))
  384.         {
  385.         buttongroup=HGroup,
  386.             MUIA_Group_SameSize, TRUE,
  387.             Child, bu_save=MakeButton(MSG_BUTTON_SAVE),
  388.             Child, bu_use=MakeButton(MSG_BUTTON_USE),
  389.             testbutton?Child:TAG_IGNORE,
  390.                 testbutton?bu_test=MakeButton(MSG_BUTTON_TEST):NULL,
  391.             Child, bu_cancel=MakeButton(MSG_BUTTON_CANCEL),
  392.             End;
  393.  
  394.         roottag->ti_Data=(ULONG)VGroup,
  395.             Child, roottag->ti_Data,
  396.             Child, buttongroup,
  397.             End;
  398.  
  399.         if (obj=(Object *)DoSuperMethodA(cl,obj,(APTR)msg))
  400.             {
  401.             data=INST_DATA(cl,obj);
  402.             data->usedefaults=usedefaults;
  403.  
  404.             /* Pool für Type SWIT_COMPLEX */
  405.  
  406.             if (data->pool=CreatePool(MEMF_CLEAR,1024,1024))
  407.                 {
  408.                 /* Buttons */
  409.  
  410.                 DoMethod(bu_save,MUIM_Notify,MUIA_Pressed,FALSE,
  411.                     obj,1,MUIM_SettingsWindow_Save);
  412.                 DoMethod(bu_use,MUIM_Notify,MUIA_Pressed,FALSE,
  413.                     obj,1,MUIM_SettingsWindow_Use);
  414.  
  415.                 if (testbutton)
  416.                     {
  417.                     DoMethod(bu_test,MUIM_Notify,MUIA_Pressed,FALSE,
  418.                         obj,3,MUIM_Set,MUIA_SettingsWindow_TestMode,TRUE);
  419.                     }
  420.  
  421.                 DoMethod(bu_cancel,MUIM_Notify,MUIA_Pressed,FALSE,
  422.                     obj,1,MUIM_SettingsWindow_Cancel);
  423.                 DoMethod(obj,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  424.                     obj,1,MUIM_SettingsWindow_Cancel);
  425.  
  426.                 /* Menu */
  427.  
  428.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_load,
  429.                     obj,1,MUIM_SettingsWindow_Load);
  430.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_defaults,
  431.                     obj,1,MUIM_SettingsWindow_Defaults);
  432.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_lastsaved,
  433.                     obj,1,MUIM_SettingsWindow_LastSaved);
  434.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_restore,
  435.                     obj,1,MUIM_SettingsWindow_Restore);
  436.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_saveas,
  437.                     obj,1,MUIM_SettingsWindow_SaveAs);
  438.                 DoMethod(obj,MUIM_Notify,MUIA_Window_MenuAction,menu_quit,
  439.                     obj,1,MUIM_SettingsWindow_Cancel);
  440.  
  441.                 NewList((struct List *)&data->notifylist);
  442.  
  443.                 erfolg=TRUE;
  444.                 }
  445.             }
  446.         }
  447.  
  448.     if (!erfolg)
  449.         {
  450.         if (obj)
  451.             {
  452.             CoerceMethod(cl,obj,OM_DISPOSE);
  453.             obj=NULL;
  454.             }
  455.         }
  456.  
  457.     return((ULONG)obj);
  458. }
  459.  
  460.  
  461. static ULONG SettingsWindow_Dispose(struct IClass *cl,Object *obj,Msg msg)
  462. {
  463.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  464.  
  465.     /* remove and free notification handlers */
  466.  
  467.     while (!IsMinListEmpty(&data->notifylist))
  468.         {
  469.         struct MinNode *mn=data->notifylist.mlh_Head;
  470.  
  471.         Remove((struct Node *)mn);
  472.         FreeVec(mn);
  473.         }
  474.  
  475.     /* free the settings items */
  476.  
  477.     if (data->items)
  478.         {
  479.         FreeVec(data->items);
  480.         }
  481.  
  482.     /* free the default items */
  483.  
  484.     if (data->defitems)
  485.         {
  486.         FreeVec(data->defitems);
  487.         }
  488.  
  489.     if (data->pool)
  490.         {
  491.         DeletePool(data->pool);
  492.         }
  493.  
  494.     return(DoSuperMethodA(cl,obj,(APTR)msg));
  495. }
  496.  
  497.  
  498. static ULONG SettingsWindow_Get(struct IClass *cl,Object *obj,struct opGet *msg)
  499. {
  500.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  501.  
  502.     switch (msg->opg_AttrID)
  503.         {
  504.         case MUIA_SettingsWindow_Changed:
  505.             *msg->opg_Storage=data->changed;
  506.             break;
  507.  
  508.         case MUIA_SettingsWindow_PortDirectly:
  509.             *msg->opg_Storage=(ULONG)data->portdirectly;
  510.             break;
  511.  
  512.         case MUIA_SettingsWindow_TestMode:
  513.             *msg->opg_Storage=(ULONG)data->testmode;
  514.             break;
  515.         default:
  516.             return(DoSuperMethodA(cl,obj,(APTR)msg));
  517.         }
  518.  
  519.     return(TRUE);
  520. }
  521.  
  522.  
  523. static ULONG SettingsWindow_Set(struct IClass *cl,Object *obj,struct opSet *msg)
  524. {
  525.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  526.  
  527.     struct TagItem *ti;
  528.     ULONG result;
  529.  
  530.     if (ti=FindTagItem(MUIA_SettingsWindow_Changed,msg->ops_AttrList))
  531.         {
  532.         if (!data->changed)
  533.             {
  534.             data->changed=ti->ti_Data;
  535.             }
  536.         else
  537.             {
  538.             ti->ti_Tag=TAG_IGNORE;
  539.             }
  540.         }
  541.  
  542.     if (ti=FindTagItem(MUIA_SettingsWindow_PortDirectly,msg->ops_AttrList))
  543.         {
  544.         data->portdirectly=ti->ti_Data;
  545.         }
  546.  
  547.     if (ti=FindTagItem(MUIA_SettingsWindow_TestMode,msg->ops_AttrList))
  548.         {
  549.         if (ti->ti_Data)
  550.             {
  551.             DoMethod(obj,MUIM_SettingsWindow_Store);
  552.  
  553.             data->testmode=TRUE;
  554.             }
  555.         else
  556.             {
  557.             data->testmode=FALSE;
  558.             }
  559.         }
  560.  
  561.     result=DoSuperMethodA(cl,obj,(APTR)msg);
  562.  
  563.     /* Reset after Notification */
  564.  
  565.     if (ti=FindTagItem(MUIA_SettingsWindow_Changed,msg->ops_AttrList))
  566.         {
  567.         data->changed=FALSE;
  568.         }
  569.  
  570.     return(result);
  571. }
  572.  
  573.  
  574. static ULONG SettingsWindow_Export(struct IClass *cl,Object *obj,struct MUIP_Export *msg)
  575. {
  576.     /* Attribute in Datei (bzw. DataspaceObject) exportieren
  577.     **    für portdirect==TRUE direkt von Objekten, sonst aus
  578.     **    SettingsWindow
  579.     */
  580.  
  581.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  582.  
  583.     ULONG i,value;
  584.  
  585.     for (i=0;i<data->itemnum;i++)
  586.         {
  587.         if (!data->portdirectly)
  588.             {
  589.             /* die settings items exportieren */
  590.  
  591.             value=SettingsWindow_GetItemNum(obj,data,i);
  592.  
  593.             switch (data->items[i].swi_Type & SWIT_TYPES)
  594.                 {
  595.                 /*    Standardattr */
  596.  
  597.                 case SWIT_STANDARD:
  598.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  599.                         &value,sizeof(LONG),
  600.                         data->items[i].swi_ID);
  601.                     break;
  602.  
  603.                 /* String */
  604.  
  605.                 case SWIT_STRING:
  606.                     if (value)
  607.                         {
  608.                         DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  609.                             value,
  610.                             strlen((STRPTR)value)+1,
  611.                             data->items[i].swi_ID);
  612.                         }
  613.                     break;
  614.  
  615.                 /* beliebig (Struktur) */
  616.  
  617.                 case SWIT_STRUCT:
  618.                     if (value)
  619.                         {
  620.                         DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  621.                             value,
  622.                             data->items[i].swi_Size,
  623.                             data->items[i].swi_ID);
  624.                         }
  625.                     break;
  626.  
  627.                 /* komplexe Struktur */
  628.  
  629.                 case SWIT_COMPLEX:
  630.                     if (value)
  631.                         {
  632.                         /* Zeiger auf Strukturanfang */
  633.  
  634.                         value-=sizeof(struct MUIS_SettingsWindow_ComplexContents);
  635.  
  636.                         DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  637.                             value,
  638.                             ((struct MUIS_SettingsWindow_ComplexContents *)value)->swc_Size,
  639.                             data->items[i].swi_ID);
  640.                         }
  641.                     break;
  642.  
  643.                 /* alle Listentypen */
  644.  
  645.                 CASE_LIST:
  646.                     if (value)
  647.                         {
  648.                         /* Zeiger auf Strukturanfang */
  649.  
  650.                         value-=sizeof(struct MUIS_SettingsWindow_ListContents);
  651.  
  652.                         DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  653.                             value,
  654.                             ((struct MUIS_SettingsWindow_ListContents *)value)->swl_Size,
  655.                             data->items[i].swi_ID);
  656.                         }
  657.                     break;
  658.  
  659.                 }
  660.             }
  661.         else
  662.             {
  663.             /* die Attribute der Objekte direkt exportieren */
  664.  
  665.             ULONG help;
  666.  
  667.             switch (data->items[i].swi_Type & SWIT_TYPES)
  668.                 {
  669.                 /* Standardattr */
  670.  
  671.                 case SWIT_STANDARD:
  672.                     get(data->items[i].swi_Obj,data->items[i].swi_Attr,&help);
  673.  
  674.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  675.                         &help, sizeof(LONG), data->items[i].swi_ID);
  676.                     break;
  677.  
  678.                 /* String */
  679.  
  680.                 case SWIT_STRING:
  681.                     get(data->items[i].swi_Obj,data->items[i].swi_Attr,&help);
  682.  
  683.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  684.                         help, strlen((STRPTR)help)+1, data->items[i].swi_ID);
  685.                     break;
  686.  
  687.                 /* beliebig (Struktur) */
  688.  
  689.                 case SWIT_STRUCT:
  690.                     get(data->items[i].swi_Obj,data->items[i].swi_Attr,&help);
  691.  
  692.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  693.                         help, data->items[i].swi_Size, data->items[i].swi_ID);
  694.                     break;
  695.  
  696.                 /* komplexe Struktur */
  697.  
  698.                 case SWIT_COMPLEX:
  699.                     help=(ULONG)Complex_SmartStore(data->items[i].swi_Obj,
  700.                         data->items[i].swi_Attr,(UWORD *)data->items[i].swi_Size,
  701.                         data->pool);
  702.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  703.                         help,
  704.                         ((struct MUIS_SettingsWindow_ComplexContents *)help)->swc_Size,
  705.                         data->items[i].swi_ID);
  706.                     FreeVecPooled(data->pool,(APTR)help);
  707.                     break;
  708.  
  709.                 /* alle Listentypen */
  710.  
  711.                 CASE_LIST:
  712.                     help=(ULONG)List_SmartStore(data->items[i].swi_Obj,
  713.                         data->items[i].swi_Type,(UWORD *)data->items[i].swi_Size,
  714.                         data->pool);
  715.                     DoMethod(msg->dataspace,MUIM_Dataspace_Add,
  716.                         help,
  717.                         ((struct MUIS_SettingsWindow_ListContents *)help)->swl_Size,
  718.                         data->items[i].swi_ID);
  719.                     FreeVecPooled(data->pool, (APTR)help);
  720.                     break;
  721.                 }
  722.             }
  723.         }
  724.  
  725.     return(0);
  726. }
  727.  
  728.  
  729. static ULONG SettingsWindow_Import(struct IClass *cl,Object *obj,struct MUIP_Import *msg)
  730. {
  731.     /* Importieren der Attribute aus Datei (Dataspaceobject)
  732.     **    für portdirect==TRUE direkt in Objekte laden, sonst in
  733.     **    SettingsWindow und dann mit Reset übernehmen
  734.     */
  735.  
  736.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  737.  
  738.     ULONG i;
  739.     ULONG *value;
  740.  
  741.     for (i=0;i<data->itemnum;i++)
  742.         {
  743.         if (value = (ULONG *)DoMethod(msg->dataspace,
  744.                 MUIM_Dataspace_Find,data->items[i].swi_ID))
  745.             {
  746.             if (!data->portdirectly)
  747.                 {
  748.                 /* in SettingsWindow importieren */
  749.  
  750.                 switch (data->items[i].swi_Type & SWIT_TYPES)
  751.                     {
  752.                     /* Standardattr */
  753.  
  754.                     case SWIT_STANDARD:
  755.                         swset(obj,data->items[i].swi_ID,*value);
  756.                         break;
  757.  
  758.                     /* String oder Struktur */
  759.  
  760.                     case SWIT_STRING:
  761.                     case SWIT_STRUCT:
  762.                         swset(obj,data->items[i].swi_ID,value);
  763.                         break;
  764.  
  765.                     /* komplexe Struktur */
  766.  
  767.                     case SWIT_COMPLEX:
  768.                         /* Relozieren in fremdem Speicherbereich!!! */
  769.  
  770.                         Complex_Reloc((APTR)value,
  771.                             (UWORD *)data->items[i].swi_Size);
  772.  
  773.                         swset(obj,data->items[i].swi_ID,(ULONG)value+sizeof(struct MUIS_SettingsWindow_ComplexContents));
  774.                         break;
  775.  
  776.                     /* alle Listentypen */
  777.  
  778.                     CASE_LIST:
  779.                         /* Relozieren in fremdem Speicherbereich!!! */
  780.  
  781.                         List_Reloc((APTR)value,data->items[i].swi_Type,
  782.                             (UWORD *)data->items[i].swi_Size);
  783.  
  784.                         swset(obj,data->items[i].swi_ID,(ULONG)value+sizeof(struct MUIS_SettingsWindow_ListContents));
  785.                         break;
  786.                     }
  787.                 }
  788.             else
  789.                 {
  790.                 /* direkt in Objekte importieren */
  791.  
  792.                 switch (data->items[i].swi_Type & SWIT_TYPES)
  793.                     {
  794.                     /* Standardattr */
  795.  
  796.                     case SWIT_STANDARD:
  797.                         set(data->items[i].swi_Obj,data->items[i].swi_Attr,*value);
  798.                         break;
  799.  
  800.                     /* String oder Struktur */
  801.  
  802.                     case SWIT_STRING:
  803.                     case SWIT_STRUCT:
  804.                         set(data->items[i].swi_Obj,data->items[i].swi_Attr,value);
  805.                         break;
  806.  
  807.                     /* komplexe Struktur */
  808.  
  809.                     case SWIT_COMPLEX:
  810.                         /* Relozieren in fremdem Speicherbereich!!! */
  811.  
  812.                         Complex_Reloc((APTR)value,
  813.                             (UWORD *)data->items[i].swi_Size);
  814.                         set(data->items[i].swi_Obj,data->items[i].swi_Attr,
  815.                             &((struct MUIS_SettingsWindow_ComplexContents *)value)->swc_Entry);
  816.                         break;
  817.  
  818.                     /* alle Listentypen */
  819.  
  820.                     CASE_LIST:
  821.                         /* Relozieren in fremdem Speicherbereich!!! */
  822.  
  823.                         List_Reloc((APTR)value,data->items[i].swi_Type,
  824.                             (UWORD *)data->items[i].swi_Size);
  825.                         List_SmartReset(data->items[i].swi_Obj,
  826.                             data->items[i].swi_Type,(APTR)value,
  827.                             (UWORD *)data->items[i].swi_Size);
  828.                         break;
  829.                     }
  830.                 }
  831.             }
  832.         }
  833.  
  834.     if (!data->portdirectly)
  835.         {
  836.         DoMethod(obj,MUIM_SettingsWindow_Reset);
  837.  
  838.         /* Notifications auf MUIA_..._Changed auslösen */
  839.  
  840.         set(obj,MUIA_SettingsWindow_Changed,TRUE);
  841.         }
  842.  
  843.     return(0);
  844. }
  845.  
  846.  
  847. static ULONG SettingsWindow_Save(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Save *msg)
  848. {
  849.     /* wie Use, nur zusätzlich ins ENVARC: speichern */
  850.  
  851.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  852.  
  853.     DoMethod(obj,MUIM_SettingsWindow_Use);
  854.  
  855.     DoMethod(_app(obj),MUIM_Application_Save,MUIV_Application_Save_ENVARC);
  856.  
  857.     return(TRUE);
  858. }
  859.  
  860.  
  861. static ULONG SettingsWindow_Use(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Use *msg)
  862. {
  863.     /*    Fenster schließen, Attribute von Objekten in Settingswindow
  864.     ** übernehmen und ins ENV: speichern
  865.     */
  866.  
  867.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  868.  
  869.     set(obj,MUIA_Window_Open,FALSE);
  870.     DoMethod(obj,MUIM_SettingsWindow_Store);
  871.     set(obj,MUIA_SettingsWindow_TestMode,FALSE);
  872.     DoMethod(_app(obj),MUIM_Application_Save,MUIV_Application_Save_ENV);
  873.  
  874.     return(TRUE);
  875. }
  876.  
  877.  
  878. static ULONG SettingsWindow_Cancel(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Cancel *msg)
  879. {
  880.     /* Fenster schließen und Objekte zurücksetzen */
  881.  
  882.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  883.  
  884.     set(obj,MUIA_Window_Open,FALSE);
  885.  
  886.     if (data->testmode)
  887.         {
  888.         /* TestMode -> zuletzt gespeichertes Laden, dann in Items */
  889.  
  890.         DoMethod(obj,MUIM_SettingsWindow_Restore);
  891.         DoMethod(obj,MUIM_SettingsWindow_Store);
  892.         set(obj,MUIA_SettingsWindow_TestMode,FALSE);
  893.         }
  894.  
  895.     else
  896.         {
  897.         /* kein TestMode -> Objekte zurücksetzen */
  898.  
  899.         DoMethod(obj,MUIM_SettingsWindow_Reset);
  900.         }
  901.  
  902.     return(TRUE);
  903. }
  904.  
  905.  
  906. static ULONG SettingsWindow_Load(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Load *msg)
  907. {
  908.     /* AslRequester öffnen und Einstellungen aus File in Objekte laden */
  909.  
  910.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  911.  
  912.     struct FileRequester *req;
  913.     STRPTR filename;
  914.     struct Window *iwin;
  915.  
  916.     get(obj,MUIA_Window_Window,&iwin);
  917.  
  918.     if (req=AllocAslRequest(ASL_FileRequest,TAG_DONE))
  919.         {
  920.         set(obj,MUIA_Window_Sleep,TRUE);
  921.  
  922.         if (AslRequestTags(req,
  923.                 ASLFR_Window, iwin,
  924.                 ASLFR_TitleText, GetStr(MSG_ASLREQ_LOAD),
  925.                 ASLFR_InitialDrawer, "SYS:Prefs/Presets",
  926.                 TAG_DONE))
  927.             {
  928.             if (strlen(req->fr_File)>0)
  929.                 {
  930.                 if (filename=AllocVec(256,MEMF_CLEAR))
  931.                     {
  932.                     strcpy(filename,req->fr_Drawer);
  933.  
  934.                     if (AddPart(filename,req->fr_File,256))
  935.                         {
  936.                         /* portdirect=TRUE -> direkt in Objekte, nicht ins
  937.                         ** SettingsWindow laden
  938.                         */
  939.  
  940.                         set(obj,MUIA_SettingsWindow_PortDirectly,TRUE);
  941.                         DoMethod(_app(obj),MUIM_Application_Load,filename);
  942.                         set(obj,MUIA_SettingsWindow_PortDirectly,FALSE);
  943.                         }
  944.  
  945.                     FreeVec(filename);
  946.                     }
  947.                 }
  948.             }
  949.  
  950.         set(obj,MUIA_Window_Sleep,FALSE);
  951.         FreeAslRequest(req);
  952.         }
  953.  
  954.     return(TRUE);
  955. }
  956.  
  957.  
  958. static ULONG SettingsWindow_Defaults(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Defaults *msg)
  959. {
  960.     /* reset to defaults */
  961.  
  962.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  963.  
  964.     ULONG i;
  965.  
  966.     if (data->defitems)
  967.     {
  968.         for (i=0;i<data->itemnum;i++)
  969.         {
  970.             switch (data->items[i].swi_Type & SWIT_TYPES)
  971.             {
  972.                 /* Standardattr */
  973.  
  974.                 case SWIT_STANDARD:
  975.                     set(data->items[i].swi_Obj,data->items[i].swi_Attr,
  976.                         data->defitems[i]);
  977.                     break;
  978.  
  979.                 /* String oder Struktur */
  980.  
  981.                 case SWIT_STRING:
  982.                 case SWIT_STRUCT:
  983.                     set(data->items[i].swi_Obj,data->items[i].swi_Attr,
  984.                         data->defitems[i]);
  985.                     break;
  986.  
  987.                 /* komplexe Struktur */
  988.  
  989.                 case SWIT_COMPLEX:
  990.                     set(data->items[i].swi_Obj,data->items[i].swi_Attr,
  991.                         &((struct MUIS_SettingsWindow_ComplexContents *)data->defitems[i])->swc_Entry);
  992.                     break;
  993.  
  994.                 /* alle Listentypen */
  995.  
  996.                 CASE_LIST:
  997.                     List_SmartReset(data->items[i].swi_Obj,
  998.                         data->items[i].swi_Type,(APTR)data->defitems[i],
  999.                         (UWORD *)data->items[i].swi_Size);
  1000.                     break;
  1001.             }
  1002.         }
  1003.     }
  1004.  
  1005.     return(TRUE);
  1006. }
  1007.  
  1008.  
  1009. static ULONG SettingsWindow_LastSaved(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_LastSaved *msg)
  1010. {
  1011.     /* zuletzt gespeicherte Einstellungen laden */
  1012.  
  1013.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1014.  
  1015.     /* portdirect=TRUE -> direkt in Objekte, nicht ins SettingsWindow */
  1016.  
  1017.     set(obj,MUIA_SettingsWindow_PortDirectly,TRUE);
  1018.     DoMethod(_app(obj),MUIM_Application_Load,MUIV_Application_Load_ENVARC);
  1019.     set(obj,MUIA_SettingsWindow_PortDirectly,FALSE);
  1020.  
  1021.     return(TRUE);
  1022. }
  1023.  
  1024.  
  1025. static ULONG SettingsWindow_Restore(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Restore *msg)
  1026. {
  1027.     /* zuletzt benutzte Einstellungen laden */
  1028.  
  1029.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1030.  
  1031.     /* portdirect=TRUE -> direkt in Objekte, nicht ins SettingsWindow */
  1032.  
  1033.     set(obj,MUIA_SettingsWindow_PortDirectly,TRUE);
  1034.     DoMethod(_app(obj),MUIM_Application_Load,MUIV_Application_Load_ENV);
  1035.     set(obj,MUIA_SettingsWindow_PortDirectly,FALSE);
  1036.  
  1037.     return(TRUE);
  1038. }
  1039.  
  1040.  
  1041. static ULONG SettingsWindow_SaveAs(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_SaveAs *msg)
  1042. {
  1043.     /* AslRequester öffnen und Einstellungen von Objekten in File
  1044.     ** speichern
  1045.     */
  1046.  
  1047.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1048.  
  1049.     struct FileRequester *req;
  1050.     STRPTR filename;
  1051.     struct Window *iwin;
  1052.  
  1053.     get(obj,MUIA_Window_Window,&iwin);
  1054.  
  1055.     if (req=AllocAslRequest(ASL_FileRequest,TAG_DONE))
  1056.         {
  1057.         set(obj,MUIA_Window_Sleep,TRUE);
  1058.  
  1059.         if (AslRequestTags(req,
  1060.                 ASLFR_Window, iwin,
  1061.                 ASLFR_TitleText, GetStr(MSG_ASLREQ_SAVEAS),
  1062.                 ASLFR_InitialDrawer, "SYS:Prefs/Presets",
  1063.                 ASLFR_DoSaveMode, TRUE,
  1064.                 TAG_DONE))
  1065.             {
  1066.             if (strlen(req->fr_File)>0)
  1067.                 {
  1068.                 if (filename=AllocVec(256,MEMF_CLEAR))
  1069.                     {
  1070.                     strcpy(filename,req->fr_Drawer);
  1071.  
  1072.                     if (AddPart(filename,req->fr_File,256))
  1073.                         {
  1074.                         /* portdirect=TRUE -> direkt von Objekten nicht vom
  1075.                         ** SettingsWindow
  1076.                         */
  1077.  
  1078.                         set(obj,MUIA_SettingsWindow_PortDirectly,TRUE);
  1079.                         DoMethod(_app(obj),MUIM_Application_Save,filename);
  1080.                         set(obj,MUIA_SettingsWindow_PortDirectly,FALSE);
  1081.                         }
  1082.  
  1083.                     FreeVec(filename);
  1084.                     }
  1085.                 }
  1086.             }
  1087.  
  1088.         set(obj,MUIA_Window_Sleep,FALSE);
  1089.         FreeAslRequest(req);
  1090.         }
  1091.  
  1092.     return(TRUE);
  1093. }
  1094.  
  1095.  
  1096. static ULONG SettingsWindow_Init(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Init *msg)
  1097. {
  1098.     /* Initialisierung des SettingsWindows */
  1099.  
  1100.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1101.  
  1102.     ULONG i=0,size=0;
  1103.     APTR    curdata;
  1104.  
  1105.     while (msg->Items[i].swi_Obj)
  1106.         {
  1107.         /* Ermittlung der Anzahl der Einträge und des benötigten Speichers */
  1108.  
  1109.         switch ((msg->Items[i].swi_Type & SWIT_TYPES))
  1110.             {
  1111.             case SWIT_STRING:
  1112.             case SWIT_STRUCT:
  1113.                 size=(size+msg->Items[i].swi_Size+3) & (~3L);
  1114.                 break;
  1115.             }
  1116.  
  1117.         i++;
  1118.         }
  1119.  
  1120.     data->itemnum=i;
  1121.     size+=sizeof(struct MUIS_SettingsWindow_Item)*data->itemnum;
  1122.  
  1123.     if (data->items=AllocVec(size,MEMF_CLEAR))
  1124.         {
  1125.         /* curdata: Pointer auf Speicher für Werte */
  1126.  
  1127.         curdata=(APTR)((ULONG)data->items+sizeof(struct MUIS_SettingsWindow_Item)*data->itemnum);
  1128.  
  1129.         for (i=0;i<data->itemnum;i++)
  1130.             {
  1131.             *((struct MUIS_SettingsWindow_Init_Item *)&data->items[i])=msg->Items[i];
  1132.  
  1133.             switch ((data->items[i].swi_Type & SWIT_TYPES))
  1134.                 {
  1135.                 /* Nur für Strings und Structs, sonst reicht swi_Contents */
  1136.  
  1137.                 case SWIT_STRING:
  1138.                 case SWIT_STRUCT:
  1139.                     data->items[i].swi_Contents=(ULONG)curdata;
  1140.                     curdata=(APTR)(((ULONG)curdata+msg->Items[i].swi_Size+3) & (~3L));
  1141.                     break;
  1142.                 }
  1143.             }
  1144.  
  1145.         /* Attribute von Objekten übernehmen, zu defaults kopieren und
  1146.         **    aktuelle Einstellungen laden
  1147.         */
  1148.  
  1149.         /* avoid double notification on MUIA_..._Changed */
  1150.  
  1151.         data->changed=TRUE;
  1152.         DoMethod(obj,MUIM_SettingsWindow_Store);
  1153.         data->changed=FALSE;
  1154.  
  1155.         /* these settings are the default ones, so copy them */
  1156.  
  1157.         if (data->usedefaults)
  1158.         {
  1159.             if (data->defitems = AllocVec(data->itemnum*sizeof(ULONG), MEMF_CLEAR))
  1160.             {
  1161.                 for (i = 0; i < data->itemnum; i++)
  1162.                 {
  1163.                     if (data->items[i].swi_Contents)
  1164.                     {
  1165.                         switch ((data->items[i].swi_Type & SWIT_TYPES))
  1166.                         {
  1167.                             /*    Standardattr. */
  1168.  
  1169.                             case SWIT_STANDARD:
  1170.                                 data->defitems[i] = data->items[i].swi_Contents;
  1171.                                 break;
  1172.  
  1173.                             /*    String */
  1174.  
  1175.                             case SWIT_STRING:
  1176.                                 data->defitems[i] = (ULONG)strdupp(data->pool,
  1177.                                     (STRPTR)data->items[i].swi_Contents);
  1178.                                 break;
  1179.  
  1180.                             /*    Struktur */
  1181.  
  1182.                             case SWIT_STRUCT:
  1183.                                 if (data->defitems[i] = (ULONG)AllocVecPooled(
  1184.                                     data->pool, data->items[i].swi_Size))
  1185.                                     memcpy((APTR)data->defitems[i],
  1186.                                         (APTR)data->items[i].swi_Contents,
  1187.                                         data->items[i].swi_Size);
  1188.                                 break;
  1189.  
  1190.                             /* komplexe Struktur */
  1191.  
  1192.                             case SWIT_COMPLEX:
  1193.                                 data->defitems[i] = (ULONG)Complex_Duplicate(
  1194.                                     (APTR)data->items[i].swi_Contents,
  1195.                                     (UWORD *)data->items[i].swi_Size, data->pool);
  1196.                                 break;
  1197.  
  1198.                             /* alle Listentypen */
  1199.  
  1200.                             CASE_LIST:
  1201.                                 data->defitems[i] =(ULONG)List_Duplicate(
  1202.                                     (struct MUIS_SettingsWindow_ListContents *)data->items[i].swi_Contents,
  1203.                                     data->items[i].swi_Type,
  1204.                                     (UWORD *)data->items[i].swi_Size, data->pool);
  1205.                                 break;
  1206.                         }
  1207.                     }
  1208.                 }
  1209.             }
  1210.         }
  1211.  
  1212.         DoMethod(_app(obj),MUIM_Application_Load,MUIV_Application_Load_ENV);
  1213.  
  1214. D(BUG("Settingswindow completely initialized!\n"));
  1215.  
  1216.         return(TRUE);
  1217.         }
  1218.  
  1219.     return(FALSE);
  1220. }
  1221.  
  1222.  
  1223. static ULONG SettingsWindow_GetItemNum(Object *obj,
  1224.     struct SettingsWindow_Data *data, ULONG num)
  1225. {
  1226.     /* Get des Items über Nummer statt über ID */
  1227.  
  1228.     if (data->items[num].swi_Type & SWIT_EMPTY)
  1229.         {
  1230.         /* Wert == NULL */
  1231.  
  1232.         return(NULL);
  1233.         }
  1234.     else
  1235.         {
  1236.         switch (data->items[num].swi_Type & SWIT_TYPES)
  1237.             {
  1238.             /* Bei Complex/Listen Zeiger auf Entry/Entrytable verschieben */
  1239.  
  1240.             case SWIT_COMPLEX:
  1241.                 return(data->items[num].swi_Contents
  1242.                     +sizeof(struct MUIS_SettingsWindow_ComplexContents));
  1243.                 break;
  1244.  
  1245.             CASE_LIST:
  1246.                 return(data->items[num].swi_Contents
  1247.                     +sizeof(struct MUIS_SettingsWindow_ListContents));
  1248.                 break;
  1249.             }
  1250.  
  1251.         return(data->items[num].swi_Contents);
  1252.         }
  1253. }
  1254.  
  1255.  
  1256. static ULONG SettingsWindow_GetItem(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_GetItem *msg)
  1257. {
  1258.     /* Äquivalent zu OM_Get */
  1259.  
  1260.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1261.  
  1262.     ULONG i;
  1263.  
  1264.     for (i=0;i<data->itemnum;i++)
  1265.         {
  1266.         if (data->items[i].swi_ID==msg->ID)
  1267.             {
  1268.             /*    ein Standardattr. oder bloß Zeiger kopieren */
  1269.  
  1270.             *msg->Storage=SettingsWindow_GetItemNum(obj,data,i);
  1271.  
  1272.             return(TRUE);
  1273.             }
  1274.         }
  1275.  
  1276.     return(FALSE);
  1277. }
  1278.  
  1279.  
  1280. static void SettingsWindow_NotifyItem(Object *obj,
  1281.     struct SettingsWindow_Data *data, ULONG itemid, ULONG itemvalue)
  1282. {
  1283.     /* notification mgl., Notificationliste parsen */
  1284.  
  1285.     if (!IsMinListEmpty(&data->notifylist))
  1286.         {
  1287.         struct NotifyEntry *ne=(struct NotifyEntry *)&data->notifylist;
  1288.  
  1289.         while (ne=(struct NotifyEntry *)ne->ne_Node.mln_Succ)
  1290.             {
  1291.             if ((itemid==ne->ne_TrigID)
  1292.                 && (ne->ne_TrigValue==MUIV_EveryTime
  1293.                     || ne->ne_TrigValue==itemvalue))
  1294.                 {
  1295.                 /* passende Notification */
  1296.  
  1297.                 ULONG *trigmsg,i;
  1298.  
  1299.                 if (trigmsg=AllocVec(4*ne->ne_FollowParams,MEMF_CLEAR))
  1300.                     {
  1301.                     Object *destobj=ne->ne_DestObj;
  1302.  
  1303.                     /*    MUIV_Notify_Self/Window/Application ersetzen */
  1304.  
  1305.                     switch ((ULONG)destobj)
  1306.                         {
  1307.                         case MUIV_Notify_Self:
  1308.                         case MUIV_Notify_Window:
  1309.                             destobj=obj;
  1310.                             break;
  1311.  
  1312.                         case MUIV_Notify_Application:
  1313.                             destobj=_app(obj);
  1314.                             break;
  1315.                         }
  1316.  
  1317.                     /*    MUIV_(Not)TriggerValue ersetzen */
  1318.  
  1319.                     for (i=0;i<ne->ne_FollowParams;i++)
  1320.                         {
  1321.                         switch (ne->ne_Params[i])
  1322.                             {
  1323.                             case MUIV_TriggerValue:
  1324.                                 trigmsg[i]=itemvalue;
  1325.                                 break;
  1326.  
  1327.                             case MUIV_NotTriggerValue:
  1328.                                 trigmsg[i]=!itemvalue;
  1329.                                 break;
  1330.  
  1331.                             default:
  1332.                                 trigmsg[i]=ne->ne_Params[i];
  1333.                             }
  1334.                         }
  1335.  
  1336.                     /* Notification ausführen */
  1337.  
  1338.                     DoMethodA(destobj,(Msg)trigmsg);
  1339.  
  1340.                     FreeVec(trigmsg);
  1341.                     }
  1342.                 }
  1343.             }
  1344.         }
  1345. }
  1346.  
  1347.  
  1348. static ULONG SettingsWindow_SetItem(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_SetItem *msg)
  1349. {
  1350.     /* Äquivalent zu MUIM_Set */
  1351.  
  1352.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1353.  
  1354.     ULONG i;
  1355.  
  1356.     for (i=0;i<data->itemnum;i++)
  1357.         {
  1358.         if (data->items[i].swi_ID==msg->ID)
  1359.             {
  1360.             /* Attribut gefunden */
  1361.  
  1362.             if (msg->Value==data->items[i].swi_Contents
  1363.                 || msg->Value==NULL && (data->items[i].swi_Type & SWIT_EMPTY))
  1364.                 {
  1365.                 /* Endlosloops vermeiden */
  1366.  
  1367.                 data->nonotify=TRUE;
  1368.                 }
  1369.  
  1370.             if (msg->Value!=NULL)
  1371.                 {
  1372.                 /* Value != NULL -> SWIT_EMPTY löschen */
  1373.  
  1374.                 data->items[i].swi_Type &= ~SWIT_EMPTY;
  1375.  
  1376.                 switch ((data->items[i].swi_Type & SWIT_TYPES))
  1377.                     {
  1378.                     /*    Standardattr. */
  1379.  
  1380.                     case SWIT_STANDARD:
  1381.                         data->items[i].swi_Contents=msg->Value;
  1382.                         break;
  1383.  
  1384.                     /*    String */
  1385.  
  1386.                     case SWIT_STRING:
  1387.                         strcpy((STRPTR)data->items[i].swi_Contents,(STRPTR)msg->Value);
  1388.                         break;
  1389.  
  1390.                     /*    Struktur */
  1391.  
  1392.                     case SWIT_STRUCT:
  1393.                         memcpy((APTR)data->items[i].swi_Contents,(APTR)msg->Value,data->items[i].swi_Size);
  1394.                         break;
  1395.  
  1396.                     /* komplexe Struktur */
  1397.  
  1398.                     case SWIT_COMPLEX:
  1399.                         if (data->items[i].swi_Contents)
  1400.                             {
  1401.                             FreeVecPooled(data->pool,(APTR)data->items[i].swi_Contents);
  1402.                             data->items[i].swi_Contents=NULL;
  1403.                             }
  1404.  
  1405.                         data->items[i].swi_Contents=(ULONG)Complex_Duplicate(
  1406.                             (APTR)(msg->Value-sizeof(struct MUIS_SettingsWindow_ComplexContents)),
  1407.                             (UWORD *)data->items[i].swi_Size,data->pool);
  1408.                         break;
  1409.  
  1410.                     /* alle Listentypen */
  1411.  
  1412.                     CASE_LIST:
  1413.                         if (data->items[i].swi_Contents)
  1414.                             {
  1415.                             FreeVecPooled(data->pool, (APTR)data->items[i].swi_Contents);
  1416.                             data->items[i].swi_Contents=NULL;
  1417.                             }
  1418.  
  1419.                         data->items[i].swi_Contents=(ULONG)List_Duplicate(
  1420.                             (APTR)(msg->Value-sizeof(struct MUIS_SettingsWindow_ListContents)),
  1421.                             data->items[i].swi_Type,
  1422.                             (UWORD *)data->items[i].swi_Size, data->pool);
  1423.                         break;
  1424.  
  1425.                     }
  1426.                 }
  1427.             else
  1428.                 {
  1429.                 /* Value == NULL -> SWIT_EMPTY setzen für korrektes Get */
  1430.  
  1431.                 data->items[i].swi_Type |= SWIT_EMPTY;
  1432.  
  1433.                 switch ((data->items[i].swi_Type & SWIT_TYPES))
  1434.                     {
  1435.                     /*    Standardattr. -> trotzdem setzen */
  1436.  
  1437.                     case SWIT_STANDARD:
  1438.                         data->items[i].swi_Contents=msg->Value;
  1439.                         break;
  1440.  
  1441.                     /*    ein String oder beliebige Daten */
  1442.  
  1443. //                    case SWIT_STRING:
  1444. //                    case SWIT_STRUCT:
  1445. //                        break;
  1446.  
  1447.                     /* komplexe Struktur */
  1448.  
  1449.                     case SWIT_COMPLEX:
  1450.                         if (data->items[i].swi_Contents)
  1451.                             {
  1452.                             FreeVecPooled(data->pool,(APTR)data->items[i].swi_Contents);
  1453.                             data->items[i].swi_Contents=NULL;
  1454.                             }
  1455.                         break;
  1456.  
  1457.                     /* alle Listentypen */
  1458.  
  1459.                     CASE_LIST:
  1460.                         if (data->items[i].swi_Contents)
  1461.                             {
  1462.                             FreeVecPooled(data->pool, (APTR)data->items[i].swi_Contents);
  1463.                             data->items[i].swi_Contents=NULL;
  1464.                             }
  1465.                         break;
  1466.                     }
  1467.                 }
  1468.  
  1469.             if (data->nonotify)
  1470.                 {
  1471.                 /*    keine Notification, data->nonotify zurücksetzen */
  1472.  
  1473.                 data->nonotify=FALSE;
  1474.                 }
  1475.             else
  1476.                 {
  1477.                 SettingsWindow_NotifyItem(obj,data,msg->ID,msg->Value);
  1478.                 }
  1479.  
  1480.             return(TRUE);
  1481.             }
  1482.         }
  1483.  
  1484.     return(FALSE);
  1485. }
  1486.  
  1487.  
  1488. static ULONG SettingsWindow_NNSetItem(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_NNSetItem *msg)
  1489. {
  1490.     /* Äquivalent zu MUIM_NoNotifySet
  1491.     ** durch nonotify=TRUE Notification verhindern, dann normales SetItem
  1492.     */
  1493.  
  1494.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1495.  
  1496.     data->nonotify=TRUE;
  1497.  
  1498.     return(SettingsWindow_SetItem(cl,obj,(APTR)msg));
  1499. }
  1500.  
  1501.  
  1502. static ULONG SettingsWindow_Notify(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Notify *msg)
  1503. {
  1504.     /* Äquivalent zu MUIM_Notify
  1505.     ** fügt Notificationhandler (=struct NotifyEntry) in NotifyList ein
  1506.     */
  1507.  
  1508.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1509.  
  1510.     struct NotifyEntry *ne;
  1511.  
  1512.     if (ne=AllocVec(sizeof(struct NotifyEntry)+msg->FollowParams*4,MEMF_CLEAR))
  1513.         {
  1514.         /* Speicher besorgt, nun kopieren und in Liste */
  1515.  
  1516.         memcpy(&ne->ne_TrigID,&msg->TrigID,NOTIFYSIZE(msg->FollowParams));
  1517.         AddTail((struct List *)&data->notifylist,(struct Node *)ne);
  1518.         return(TRUE);
  1519.         }
  1520.  
  1521.     return(FALSE);
  1522. }
  1523.  
  1524.  
  1525. static ULONG SettingsWindow_KillNotify(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_KillNotify *msg)
  1526. {
  1527.     /* Äquivalent zu MUIM_KillNotify
  1528.     ** entfernt Notificationhandler (=struct NotifyEntry) aus NotifyList
  1529.     */
  1530.  
  1531.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1532.  
  1533.     struct NotifyEntry *ne=(struct NotifyEntry *)&data->notifylist;
  1534.  
  1535.     while ((ne=(struct NotifyEntry *)ne->ne_Node.mln_Succ)
  1536.         && (msg->TrigID!=ne->ne_TrigID))
  1537.         {
  1538.         }
  1539.  
  1540.     if (ne)
  1541.         {
  1542.         /* Notificationhandler gefunden - removen und freigeben */
  1543.  
  1544.         Remove((struct Node *)ne);
  1545.         FreeVec(ne);
  1546.  
  1547.         return(TRUE);
  1548.         }
  1549.  
  1550.     return(FALSE);
  1551. }
  1552.  
  1553.  
  1554. static ULONG SettingsWindow_KillNotifyObj(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_KillNotifyObj *msg)
  1555. {
  1556.     /* Äquivalent zu MUIM_KillNotifyObj
  1557.     ** entfernt Notificationhandler (=struct NotifyEntry) aus NotifyList
  1558.     */
  1559.  
  1560.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1561.  
  1562.     struct NotifyEntry *ne=(struct NotifyEntry *)&data->notifylist;
  1563.  
  1564.     while ((ne=(struct NotifyEntry *)ne->ne_Node.mln_Succ)
  1565.         && (msg->TrigID!=ne->ne_TrigID)
  1566.         && (msg->DestObj!=ne->ne_DestObj))
  1567.         {
  1568.         }
  1569.  
  1570.     if (ne)
  1571.         {
  1572.         /* Notificationhandler gefunden - removen und freigeben */
  1573.  
  1574.         Remove((struct Node *)ne);
  1575.         FreeVec(ne);
  1576.  
  1577.         return(TRUE);
  1578.         }
  1579.  
  1580.     return(FALSE);
  1581. }
  1582.  
  1583.  
  1584. static ULONG SettingsWindow_Reset(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Reset *msg)
  1585. {
  1586.     /* Zurücksetzen der Objekte auf Einstellungen des SettingsWindows */
  1587.  
  1588.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1589.  
  1590.     ULONG i,value;
  1591.  
  1592. D(BUG("SettingsWindow_Reset\n"));
  1593.  
  1594.     for (i=0;i<data->itemnum;i++)
  1595.         {
  1596.         value=SettingsWindow_GetItemNum(obj,data,i);
  1597.  
  1598.         D(BUG("Item: %ld (%p), value: %p\n",i,data->items[i].swi_Type,value));
  1599.  
  1600.         switch (data->items[i].swi_Type & SWIT_TYPES)
  1601.             {
  1602.             /* Standard, String, Struktur und komplexe Struktur */
  1603.  
  1604.             case SWIT_STANDARD:
  1605.             case SWIT_STRING:
  1606.             case SWIT_STRUCT:
  1607.             case SWIT_COMPLEX:
  1608.                 set(data->items[i].swi_Obj,data->items[i].swi_Attr,
  1609.                     value);
  1610.                 break;
  1611.  
  1612.             /* alle Listentypen */
  1613.  
  1614.             CASE_LIST:
  1615.                 D(BUG("ListString!\n"));
  1616.                 List_Reset(&data->items[i]);
  1617.                 break;
  1618.             }
  1619.         }
  1620.  
  1621. D(BUG("SettingsWindow_Reset End\n"));
  1622.  
  1623.     return(TRUE);
  1624. }
  1625.  
  1626.  
  1627. static ULONG SettingsWindow_Store(struct IClass *cl,Object *obj,struct MUIP_SettingsWindow_Store *msg)
  1628. {
  1629.     /* Übernehmen der Attribute von Objekten ins SettingsWindow */
  1630.  
  1631.     struct SettingsWindow_Data *data=INST_DATA(cl,obj);
  1632.  
  1633.     ULONG i,help;
  1634.  
  1635. D(BUG("SettingsWindow_Store\n"));
  1636.  
  1637.     for (i=0;i<data->itemnum;i++)
  1638.         {
  1639.         switch(data->items[i].swi_Type & SWIT_TYPES)
  1640.             {
  1641.             /* Standard, String und Struktur */
  1642.  
  1643.             case SWIT_STANDARD:
  1644.             case SWIT_STRING:
  1645.             case SWIT_STRUCT:
  1646.                 get(data->items[i].swi_Obj,data->items[i].swi_Attr,&help);
  1647.                 swset(obj,data->items[i].swi_ID,help);
  1648.                 break;
  1649.  
  1650.             /* komplexe Struktur */
  1651.  
  1652.             case SWIT_COMPLEX:
  1653.                 Complex_Store(&data->items[i],data->pool);
  1654.                 SettingsWindow_NotifyItem(obj,data,data->items[i].swi_ID,
  1655.                     data->items[i].swi_Contents
  1656.                     +sizeof(struct MUIS_SettingsWindow_ComplexContents));
  1657.                 break;
  1658.  
  1659.             /* alle Listentypen */
  1660.  
  1661.             CASE_LIST:
  1662.                 List_Store(&data->items[i], data->pool);
  1663.                 SettingsWindow_NotifyItem(obj,data,data->items[i].swi_ID,
  1664.                     data->items[i].swi_Contents
  1665.                     +sizeof(struct MUIS_SettingsWindow_ListContents));
  1666.                 break;
  1667.             }
  1668.         }
  1669.  
  1670.     /* Notifications auf MUIA_..._Changed auslösen */
  1671.  
  1672.     set(obj,MUIA_SettingsWindow_Changed,TRUE);
  1673.  
  1674. D(BUG("SettingsWindow_Store End\n"));
  1675.  
  1676.     return(TRUE);
  1677. }
  1678.  
  1679.  
  1680.  
  1681. static SAVEDS ASM ULONG SettingsWindow_Dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  1682. {
  1683.     switch (msg->MethodID)
  1684.         {
  1685.         case OM_NEW                                            : return(SettingsWindow_New                    (cl,obj,(APTR)msg));
  1686.         case OM_GET                                            : return(SettingsWindow_Get                    (cl,obj,(APTR)msg));
  1687.         case OM_SET                                            : return(SettingsWindow_Set                    (cl,obj,(APTR)msg));
  1688.         case MUIM_Export                                    : return(SettingsWindow_Export                (cl,obj,(APTR)msg));
  1689.         case MUIM_Import                                    : return(SettingsWindow_Import                (cl,obj,(APTR)msg));
  1690.         case MUIM_SettingsWindow_Save                    : return(SettingsWindow_Save                    (cl,obj,(APTR)msg));
  1691.         case MUIM_SettingsWindow_Use                    : return(SettingsWindow_Use                    (cl,obj,(APTR)msg));
  1692.         case MUIM_SettingsWindow_Cancel                : return(SettingsWindow_Cancel                (cl,obj,(APTR)msg));
  1693.         case MUIM_SettingsWindow_Load                    : return(SettingsWindow_Load                    (cl,obj,(APTR)msg));
  1694.         case MUIM_SettingsWindow_Defaults            : return(SettingsWindow_Defaults                (cl,obj,(APTR)msg));
  1695.         case MUIM_SettingsWindow_LastSaved            : return(SettingsWindow_LastSaved            (cl,obj,(APTR)msg));
  1696.         case MUIM_SettingsWindow_Restore                : return(SettingsWindow_Restore                (cl,obj,(APTR)msg));
  1697.         case MUIM_SettingsWindow_SaveAs                : return(SettingsWindow_SaveAs                (cl,obj,(APTR)msg));
  1698.         case MUIM_SettingsWindow_Init                    : return(SettingsWindow_Init                    (cl,obj,(APTR)msg));
  1699.         case MUIM_SettingsWindow_GetItem                : return(SettingsWindow_GetItem                (cl,obj,(APTR)msg));
  1700.         case MUIM_SettingsWindow_SetItem                : return(SettingsWindow_SetItem                (cl,obj,(APTR)msg));
  1701.         case MUIM_SettingsWindow_NNSetItem            : return(SettingsWindow_NNSetItem            (cl,obj,(APTR)msg));
  1702.         case MUIM_SettingsWindow_Notify                : return(SettingsWindow_Notify                (cl,obj,(APTR)msg));
  1703.         case MUIM_SettingsWindow_KillNotify            : return(SettingsWindow_KillNotify            (cl,obj,(APTR)msg));
  1704.         case MUIM_SettingsWindow_KillNotifyObj        : return(SettingsWindow_KillNotifyObj        (cl,obj,(APTR)msg));
  1705.         case MUIM_SettingsWindow_Reset                : return(SettingsWindow_Reset                    (cl,obj,(APTR)msg));
  1706.         case MUIM_SettingsWindow_Store                : return(SettingsWindow_Store                    (cl,obj,(APTR)msg));
  1707.         case OM_DISPOSE                                    : return(SettingsWindow_Dispose                (cl,obj,(APTR)msg));
  1708.         }
  1709.  
  1710.     return(DoSuperMethodA(cl,obj,msg));
  1711. }
  1712.  
  1713.  
  1714.  
  1715. /***********************/
  1716. /*  MCC/Library stuff  */
  1717. /***********************/
  1718.  
  1719.  
  1720. LONG ASM MCC_Init(REG(a6) struct Library *mybase)
  1721. {
  1722.     SysBase = *((struct Library **)4);
  1723.     MUIClassBase = mybase;
  1724.  
  1725.     InitLocale();
  1726.  
  1727.     if (MUIMasterBase = OpenLibrary("muimaster.library",8))
  1728.         {
  1729.         if (AslBase = OpenLibrary("asl.library",0))
  1730.             {
  1731.             if (ThisClass = MUI_CreateCustomClass(mybase,SUPERCLASS,NULL,sizeof(struct SettingsWindow_Data),SettingsWindow_Dispatcher))
  1732.                 {
  1733.                 UtilityBase        = ThisClass->mcc_UtilityBase;
  1734.                 DOSBase            = ThisClass->mcc_DOSBase;
  1735.                 IntuitionBase    = ThisClass->mcc_IntuitionBase;
  1736.                 GfxBase            = ThisClass->mcc_GfxBase;
  1737.  
  1738.                 DBINIT;
  1739.  
  1740.                 return(0);
  1741.                 }
  1742.  
  1743.             CloseLibrary(AslBase);
  1744.             }
  1745.  
  1746.         CloseLibrary(MUIMasterBase);
  1747.         }
  1748.  
  1749.     if (LocaleBase)
  1750.         {
  1751.         CloseLibrary(LocaleBase);
  1752.         }
  1753.  
  1754.     return(-1);
  1755. }
  1756.  
  1757.  
  1758. void ASM MCC_Cleanup(REG(a6) struct Library *mybase)
  1759. {
  1760.     DBEXIT;
  1761.  
  1762.     if (MUIMasterBase)
  1763.         {
  1764.         if (ThisClass) MUI_DeleteCustomClass(ThisClass);
  1765.         CloseLibrary(MUIMasterBase);
  1766.         }
  1767.  
  1768.     if (AslBase)
  1769.         {
  1770.         CloseLibrary(AslBase);
  1771.         }
  1772.  
  1773.     ExitLocale();
  1774. }
  1775.  
  1776.  
  1777. SAVEDS ASM struct MUI_CustomClass *MCC_GetClass(REG(d0) LONG which)
  1778. {
  1779.     switch (which)
  1780.         {
  1781.         case 0: return(ThisClass);
  1782.         }
  1783.  
  1784.     return(NULL);
  1785. }
  1786.  
  1787.  
  1788.  
  1789. /*
  1790. ************************
  1791. *  Anmerkungen / Bugs  *
  1792. ************************
  1793.  
  1794.  
  1795. * HACK: Relocating in unknown memory area: MUIM_Import->portdirectly->Lists
  1796.  
  1797.  
  1798.  
  1799. */
  1800.